/**
 * futures : masterlink.futures.dao.GroupDao.java
 */
package masterlink.futures.dao;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import masterlink.futures.vo.Account;
import masterlink.futures.vo.Equity;
import masterlink.futures.vo.Fuhiva;
import masterlink.futures.vo.Fuhivc;
import masterlink.futures.vo.GreekConclusion;
import masterlink.futures.vo.GreekVerbS;
import masterlink.futures.vo.Group;

import org.hibernate.type.StandardBasicTypes;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import baytony.util.Util;

/**
 * TODO Write the description
 *
 * @author : tonyyang
 * Create date : 2011/10/25
 * @version 1.0.0	
 */
@Repository
@Qualifier("EquityDao")
public class EquityDao extends TimesTenTemplateDao{
	
	private static final SimpleDateFormat df=new SimpleDateFormat("yyyyMMdd"); 
	private static final String FIND_ALL="select distinct {b.*},{c.*},{d.*},{e.*},{f.*},g.t_balance " +
											"from greeks_limit a,fuminv b, greeks_conclusion c, " +
											"(select * from greeks_verb where rate=1) d, fuhivc e, fuhiva f, " +
											"(select acno,broker_id,sum(balance) as t_balance from fuhivabal where date1>=? and date1<=? "+
											"group by acno,broker_id) g "+
											"where a.account=b.acno and a.broker=b.broker_id "+
											"and a.account=c.account(+) and a.broker=c.broker(+) "+
											"and a.account=d.account(+) and a.broker=d.broker(+) and (d.rate=1 or d.rate is null) "+
											"and a.account=e.acno(+) and a.broker=e.broker_id(+) "+
											"and a.account=f.acno(+) and a.broker=f.broker_id(+) " +
											"and a.account=g.acno(+) and a.broker=g.broker_id(+) " ;
	@SuppressWarnings("unchecked")
	public List<Equity> findAll() {
		return create((List<Object[]>) executeQuery(createSqllQuery(FIND_ALL)
				.addEntity("b", Account.class).addEntity("c",GreekConclusion.class)
				.addEntity("d",GreekVerbS.class).addEntity("e",Fuhivc.class).addEntity("f",Fuhiva.class)
				.addScalar("t_balance", StandardBasicTypes.LONG)
				,getStart(),getEnd()));
	}
	
	@SuppressWarnings("unchecked")
	public List<Equity> findByGroup(Group group) {
		if(group!=null){
			return create((List<Object[]>) executeQuery(createSqllQuery(FIND_ALL+"and a.id=? order by b.acno, d.setmonth asc")
				.addEntity("b", Account.class).addEntity("c",GreekConclusion.class)
				.addEntity("d",GreekVerbS.class).addEntity("e",Fuhivc.class).addEntity("f",Fuhiva.class)
				.addScalar("t_balance", StandardBasicTypes.LONG)
				,getStart(),getEnd(),group.getId()));
		}
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public List<Equity> findByAccount(Group group,Account acc) {
		if(group!=null&&acc!=null){
		return create((List<Object[]>) executeQuery(createSqllQuery(FIND_ALL+"and a.id=? and a.account=? order by b.acno, d.setmonth asc")
				.addEntity("b", Account.class).addEntity("c",GreekConclusion.class)
				.addEntity("d",GreekVerbS.class).addEntity("e",Fuhivc.class).addEntity("f",Fuhiva.class)
				.addScalar("t_balance", StandardBasicTypes.LONG)
				,getStart(),getEnd(),group.getId(),acc.getId().getAcno()));
		}
		return null;
	}
	
	
	private List<Equity> create(List<Object[]> all){
		List<Equity> res=new ArrayList<Equity>();
		if(!Util.isEmptyList(all)){
			for(Object[] o:all){
				Account acc=(Account)evict(o[0]);
				GreekConclusion cc=(GreekConclusion)evict(o[1]);
				GreekVerbS cv=(GreekVerbS)evict(o[2]);
				Fuhivc fc=(Fuhivc)evict(o[3]);
				Fuhiva fv=(Fuhiva)evict(o[4]);
				Long balance=(Long)evict(o[5]);
				Equity e=new Equity(acc, cc,cv, fc, fv,balance);
				res.add(e);
			}
		}
		log.trace("{} of Equity was found.",res.size());
		return res;
	}
	
	private Long getStart(){
		Calendar cal=new GregorianCalendar();
		cal.set(Calendar.DAY_OF_MONTH, cal.getMinimum(Calendar.DAY_OF_MONTH));
		return Long.valueOf(df.format(cal.getTime()));
	}
	
	private Long getEnd(){
		Calendar cal=new GregorianCalendar();
		cal.set(Calendar.DAY_OF_MONTH, cal.getMaximum(Calendar.DAY_OF_MONTH));
		return Long.valueOf(df.format(cal.getTime()));
	}

	
}
